package ling.archives.domain.dto;
import java.util.ArrayList;
import java.util.List;


import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import ling.archives.common.ExcelHandle;
import ling.archives.common.ValidUtil;
import ling.archives.common.domain.Result;
import ling.archives.domain.Archive;
import lombok.Data;
import lombok.var;
import org.apache.poi.ss.usermodel.Row;

import javax.validation.Validation;
import javax.validation.constraints.*;
import javax.validation.constraints.Pattern;


/** 档案记录类
 *
 */

@Data
public class ArchiveXls implements ExcelHandle.rowSetHeader{

    public static List<String> check(List<ArchiveXls> list) {
        var list2 = new ArrayList<String>();
        for (var item : list) {
            var msg = ValidUtil.validToStr(item);
            if (StringUtils.isNotBlank(msg))
                list2.add("第"+(item.dataRowNum)+"行:"+msg);
        }
        return list2;
    }


//    public Result<String> checkOtherTitle(String title){
//        var allTitleReg="^各乡(\\d{4}-\\d{4})年度农宅使用证买卖存根$";//各乡1989-1990年度农宅使用证买卖存根
//        var re=strGroupsByRegex(title,allTitleReg);
//        if(re==null)
//            return Result.bad("各乡匹配失败");
//        else
//            return Result.ok("各乡");
//    }

    /**
     * 将数字范围字符串转换为三位数格式（补零）
     * 例如: "1-41" -> "001-041"
     * @param range 原始数字范围字符串
     * @return 补零后的三位数范围字符串
     */
    public static String formatNumberRange(String range) {
        if (range == null || !range.contains("-")) {
            return range;
        }
        String[] parts = range.split("-");
        if (parts.length != 2) {
            return range;
        }
        try {
            String start = String.format("%03d", Integer.parseInt(parts[0].trim()));
            String end = String.format("%03d", Integer.parseInt(parts[1].trim()));
            return start + "-" + end;
        } catch (NumberFormatException e) {
            return range;
        }
    }

    public static String[] strGroupsByRegex(String input, String regex) {
        var pattern = java.util.regex.Pattern.compile(regex);
        var matcher = pattern.matcher(input);

        if (!matcher.matches())
            return null;
            
            try {
                // 如果是第一个分支（1,2,3组）
                if (matcher.group(1) != null) {
                    return new String[]{matcher.group(1), matcher.group(2), matcher.group(3)};
                }
                // 如果是第二个分支（4,5,6组）
                else if (matcher.group(4) != null) {
                    return new String[]{matcher.group(4), matcher.group(5), matcher.group(6)};
                }
                // 如果是第三个分支（7,8组）
                else if (matcher.group(7) != null) {
                    return new String[]{matcher.group(7), matcher.group(8)};
                }
                // 如果是第四个分支（农宅更换使用证申请表）
                else if (matcher.group(9) != null) {
                    return new String[]{matcher.group(9)};
                }
                // 如果是第五个分支（农房建设许可证）
                else if (matcher.group(10) != null) {
                    return new String[]{matcher.group(10)};
                }
                return null;
            } catch (Exception e) {
            // 如果获取捕获组出错，返回null而不是抛出异常
            return null;
        }
    }
    public String validObj(Object obj) {
        var factory = Validation.buildDefaultValidatorFactory();
        var validator = factory.getValidator();

        var violations = validator.validate(obj);
        StringBuilder msg = new StringBuilder();
        for (var violation : violations) {
            msg.append(violation.getMessage()).append(";");
        }
        return msg.toString();
    }

    public Archive toEntity() {
        var archive = new Archive();
        archive.setStatus("0");
        archive.setFullArchiveName(全宗名称);
        archive.setDirNum(目录号);
        archive.setFullNum(档号);
        archive.setTitle(案卷题名);
        archive.setYear(Integer.parseInt(年度));
        archive.setFullArchiveNum(全宗号);
        archive.setNum(案卷号);
        archive.setManager(责任者);
        archive.setStartDate(DateUtils.dateTime("yyyyMMdd", 起始日期));
        archive.setEndDate(DateUtils.dateTime("yyyyMMdd", 终止日期));
        archive.setTotalFile(Integer.parseInt(卷内文件份数));
        archive.setTotalPage(Integer.parseInt(总页数));
        //
        if (案卷题名.startsWith("各乡")) {
            archive.setTownName("各乡"); //各乡1989-1990年度农宅使用证买卖存根
            archive.setFilePath(archive.getNum() + "-" + 案卷题名 + "（档）");
        } 
        else if (案卷题名.matches("^\\d{4}-\\d{4}年度用地许可证存根$")) {
            archive.setTownName("其他"); //2003-2004年度用地许可证存根
            archive.setFilePath(archive.getNum() + "-" + 案卷题名 );
        } 
        else {
            var pattern = java.util.regex.Pattern.compile(titleReg);
            var matcher = pattern.matcher(案卷题名);
            if (matcher.matches()) {
                var titleInfos = strGroupsByRegex(案卷题名, titleReg);
                var numInfos = strGroupsByRegex(档号, fullNumReg);
                
                // 第一个分支匹配（1,2,3组）
                if (matcher.group(1) != null) {
                    archive.setTownName(titleInfos[0]);
                    archive.setFilePath(archive.getNum() + "-" + archive.getTownName() + archive.getYear() + "年度" + titleInfos[2] + "号");
                }
                // 第二个分支匹配（4,5,6组）
                else if (matcher.group(4) != null) {
                    archive.setTownName(titleInfos[0]);
                    // 提取搬迁号码（如果有）
                    List<String> moveNums = new ArrayList<>();
                    int startSearchIndex = 0;
                    while (true) {
                        int moveIndex = -1;
                        String[] types = {"、搬", "、迁", "、退", "、扩", "、更", "、水灾"};
                        for (String type : types) {
                            int idx = 案卷题名.indexOf(type, startSearchIndex);
                            if (idx != -1 && (moveIndex == -1 || idx < moveIndex)) {
                                moveIndex = idx;
                            }
                        }
                        if (moveIndex == -1) break;
                        
                        int startIndex;
                        if(案卷题名.indexOf("、水灾", moveIndex) == moveIndex) {
                            startIndex = moveIndex + 3;  // 跳过"、水灾"
                        } else {
                            startIndex = moveIndex + 2;  // 跳过"、X"（X是搬迁退扩更中的一个）
                        }
                        int endIndex = 案卷题名.indexOf("号", startIndex);
                        if (endIndex > startIndex) {
                            String numPart = 案卷题名.substring(startIndex, endIndex);
                            moveNums.add(案卷题名.substring(moveIndex + 1, startIndex) + formatNumberRange(numPart) + "号");
                        }
                        startSearchIndex = endIndex + 1;
                    }
                    String moveNum = String.join("、", moveNums);
                    String suffix = (moveNum.isEmpty() ? "" : "、" + moveNum) + 
                                  (案卷题名.contains("（异地安置）") ? "（异地安置）" : "");
                    archive.setFilePath(archive.getNum() + "-" + archive.getTownName() + "（镇）" + archive.getYear() + "年度" + (titleInfos[2] != null ? formatNumberRange(titleInfos[2]) + "号" : "") + suffix);
                }
                // 第三个分支匹配（7,8组）
                else if (matcher.group(7) != null) {
                    if (titleInfos[0].equals("城关乡")){
                        archive.setTownName("城关镇");
                    }else
                    archive.setTownName(titleInfos[0]);
                    archive.setFilePath(archive.getNum() + "-" + archive.getTownName());
                }
                // 第四个分支匹配（农宅更换使用证申请表）
                else if (matcher.group(9) != null) {
                    archive.setTownName(titleInfos[0]);
                    archive.setFilePath(archive.getNum() + "-" + 案卷题名);
                }
                // 第五个分支匹配（农房建设许可证）
                else if (matcher.group(10) != null) {
                    archive.setTownName(titleInfos[0]);
                    archive.setFilePath(archive.getNum() + "-" + archive.getTownName());
                }
            }
        }
        return archive;
    }

    public final static String hzReg ="(?:[\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uF900-\\uFAFF]|[\\uD840-\\uD868\\uD86A-\\uD872\\uD879-\\uD87C][\\uDC00-\\uDFFF]|\\uD869[\\uDC00-\\uDEDF\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF3F]|\\uD86E[\\uDC00-\\uDC1F]|\\uD87E[\\uDC00-\\uDE1F])";
    //"^([\\u4e00-\\u9fa5]+[乡|镇])（镇）(\\d{4})年度宅基地使用证存根(\\d{3,}-\\d{3,})号$"
     public final static String  titleReg= "^(?:各乡\\d{4}-\\d{4}年度农宅使用证买卖存根)$" +
             "|^(?:\\d{4}-\\d{4}年度用地许可证存根)$" +
             "|^("+ hzReg +"+[乡|镇])(?:[\\\\(（]镇[\\\\)）])?(\\d{4})年度(?:宅基地|农宅)使用证存根(\\d{1,}-\\d{1,})号$" +
             "|^("+ hzReg +"+[乡|镇])(?:[\\\\(（]镇[\\\\)）])?(\\d{4})年度用地许可证存根(?:(\\d{1,}-\\d{1,})号)?(?:、(?:搬|迁|退|扩|水灾|更)\\d{1,}-\\d{1,}号)*(?:（异地安置）)?$" +
             "|^("+ hzReg +"+[乡|镇])(?:[\\\\(（]镇[\\\\)）])?(\\d{4})年度用地许可证$" +
             "|^("+ hzReg +"+(?:、"+ hzReg +"+)*)农宅更换使用证申请表$" +
             "|^("+ hzReg +"+(?:、"+ hzReg +"+)*)农房建设许可证$";
    public final static String  fullNumReg="0099-(?:(?:用地许可证存根·|农宅用地许可证·|农宅更换补办·|农房建设许可证·)?(?:19|20)\\d{2})-永久-(\\d{4})";
    public final static String dateReg="^(?:19|20)\\d{2}[01]\\d[0123]\\d$";
    @Excel(name = "档案馆代码")
    private String 档案馆代码;

    @Excel(name = "著录层级")
    private String 著录层级;

    @Excel(name = "全宗名称")
    private String 全宗名称;

    @Excel(name = "档案门类代码")
    private String 档案门类代码;

    @Excel(name = "保管期限")
    private String 保管期限;

    @Pattern(message = "格式错误",regexp = "\\d{4}")
    @Excel(name = "全宗号")
    private String 全宗号;

    @Excel(name = "年度")
    @Digits(integer = 4,fraction = 0)
    private String 年度;

    @Excel(name = "档号")
    @NotBlank
    @Pattern(message = "格式错误",regexp = fullNumReg)
    private String 档号;

    @Excel(name = "目录号")
    private String 目录号;

    @Excel(name = "案卷号")
    @Pattern(message = "格式错误",regexp = "\\d{4}")
    private String 案卷号;

    @Excel(name = "案卷题名")
    @NotBlank
    @Pattern(regexp =titleReg,message = "格式错误")
    private String 案卷题名;

    @Excel(name = "责任者")
    private String 责任者;

    @Pattern(regexp = dateReg, message = "日期格式应为yyyyMMdd")
    @Excel(name = "起始日期")
    private String 起始日期;

    @Pattern(regexp = dateReg, message = "日期格式应为yyyyMMdd")
    @Excel(name = "终止日期")
    private String 终止日期;


    @Digits(integer = 4,fraction = 0)
    @Excel(name = "卷内文件份数")
    private String 卷内文件份数;

    @Digits(integer = 4,fraction = 0)
    @Excel(name = "总页数")
    private String 总页数;

    @Excel(name = "主题词或关键词")
    private String 主题词或关键词;

    @Excel(name = "机构或问题")
    private String 机构或问题;

    @Excel(name = "盒号")
    private String 盒号;

    @Excel(name = "存放位置")
    private String 存放位置;

    @Excel(name = "密级")
    private String 密级;

    @Excel(name = "开放标识")
    private String 开放标识;

    @Excel(name = "分类号")
    private String 分类号;

    @Excel(name = "载体形态")
    private String 载体形态;

    @Excel(name = "计算机文件大小")
    private String 计算机文件大小;

    @Excel(name = "计算机文件格式")
    private String 计算机文件格式;

    @Excel(name = "生成方式")
    private String 生成方式;

    @Excel(name = "销毁情况")
    private String 销毁情况;

    @Excel(name = "缩微号")
    private String 缩微号;

    @Excel(name = "备注")
    private String 备注;

    @Excel(name = "档案门类")
    private String 档案门类;

    @Excel(name = "开放控制")
    private String 开放控制;

    @Excel(name = "档案开放")
    private String 档案开放;

    @Excel(name = "开放状态")
    private String 开放状态;

    @Excel(name = "实体份数")
    private String 实体份数;

    @Excel(name = "流程分组状态")
    private String 流程分组状态;

    @Excel(name = "档案划控状态")
    private String 档案划控状态;

    @Excel(name = "档案销毁状态")
    private String 档案销毁状态;

    @Excel(name = "划控鉴定审批状态")
    private String 划控鉴定审批状态;

    @Excel(name = "销毁鉴定审批状态")
    private String 销毁鉴定审批状态;

    @Excel(name = "密级鉴定审批状态")
    private String 密级鉴定审批状态;

    @Excel(name = "移交审批状态")
    private String 移交审批状态;

    @Excel(name = "移交失败原因")
    private String 移交失败原因;

    @Excel(name = "归档审批状态")
    private String 归档审批状态;

    @Excel(name = "归档失败原因")
    private String 归档失败原因;

    /** 内页信息
     *
     */
    List<ArchiveContentXls> contents;
    Integer dataRowNum;
    @Override
    public void after(Row row) {
        dataRowNum=row.getRowNum();
    }
}